﻿using System;
using System.Collections.Generic;
using XFControls.Utils;
using XFControls.XFPanels.XFPanelItems;
using System.Drawing;
using XFControls.XFPanels;
using XFSenseUI.XFItems.SenseControls;
using System.Windows.Forms;
using XFControls;

namespace XFSenseUI.XFItems
{
    public class SenseItemTextBox : SenseItemBase
    {
        public event EventHandler<TextEventArgs> TextChanged;
        public event EventHandler SendButtonClicked;
        public SenseControlTextBox Control = new SenseControlTextBox();
        public TextBox TextBox { get { return Control.TextBox; } set { Control.TextBox = value; } }
        public string Description { get; set; }
        public bool SendButton { get { return Control.SendButton; } set { Control.SendButton = value; } }

        public string Text { get { return Control.Text; } set { Control.Text = value; } }

        private string _oldText;
        private int _height;
        private const int _linespace = 5;
        private Rectangle _descRec;
        private List<MenuItem> _contextMenu;
        private bool _inSend;

        public SenseItemTextBox()
        {
            Init();
        }

        public override int GetHeight()
        {
            if (_height > 0)
                return _height;

            if (!string.IsNullOrEmpty(Description))
            {
                _descRec = new Rectangle(0, 0, GetWidth() - (Style.PaddingLeft + Style.PaddingRight), 0);
                int height = Style.SecondaryTextFont.MeasureString(Description, _descRec).Height;
                _descRec.Height = height;
            }

            _height = Control.GetHeight() + Style.PaddingTop + Style.PaddingBottom + _descRec.Height + _linespace;

            return _height;
        }

        public override void ResetHeight()
        {
            _height = -1;
        }

        public override void ItemPaint(Graphics g, int x, int y)
        {
            base.ItemPaint(g, x, y);

            int localY = y + Style.PaddingTop;
            int localX = x + Style.PaddingLeft;

            if (!string.IsNullOrEmpty(Description))
            {
                _descRec.X = localX;
                _descRec.Y = localY;
                using (var b = new SolidBrush(Style.SecondaryTextColor))
                    g.DrawString(Description, Style.SecondaryTextFont, b, _descRec);
                localY += _descRec.Height + _linespace;
            }

            Control.ItemPaint(g, localX, localY);
        }

        public void SetHeight(int height)
        {
            int minHeight = this.GetImageRec("textbox").Height;
            if (height < minHeight)
            {
                Control.TextBox.Multiline = false;
                return;
            }

            Control.TextBox.Multiline = true;
            var rec = Control.ItemRectangle;
            Control.ItemRectangle = new Rectangle(rec.X, rec.Y, rec.Width, height);
        }

        public override void OnMouseDown(int x, int y)
        {
            base.OnMouseDown(x, x);
            _inSend = Control.SendRec.Contains(x, y);
            Control.OnMouseDown(x, y);
        }

        public override void OnMouseMove(int x, int y)
        {
            base.OnMouseMove(x, y);
            Control.OnMouseMove(x, y);
        }

        public override void OnMouseUp()
        {
            base.OnMouseUp();
            if (Parent.State == States.Click && _inSend && SendButtonClicked != null)
                SendButtonClicked(this,new EventArgs());
            Control.OnMouseUp();
        }

        public override void OnFocus()
        {
            base.OnFocus();
            Control.OnFocus();
            ReplaceMenuItems();
            if (Parent != null)
            {
                if (Parent is XFPanelList)
                {
                    int height = GetHeight();
                    if (Parent.Parent != null && Parent.Parent is XFPanelContainer)
                        height += ((XFPanelContainer)Parent.Parent).SIPHeight;
                    var localY = ((XFPanelList)Parent).MakeItemVisible(this, height);
                    TextBox.Location = new Point(TextBox.Location.X, TextBox.Location.Y + Math.Abs(localY));
                }

                Parent.ShowTextInput(TextBox);
            }

            TextBox.Focus();
            _oldText = Text;
        }

        public override void OnBlur()
        {
            base.OnBlur();
            RestoreMenuItems();
            if (Parent != null)
            {
                Parent.HideTextInput(TextBox);
            }
            Control.OnBlur();

            Invalidate(true);
        }

        public override void OnScreenResize()
        {
            base.OnScreenResize();
            Control.OnScreenResize();
            throw new NotImplementedException();
        }

        private void Init()
        {
            int width = GetWidth();
            int padding = (width - Control.GetWidth()) >> 1;

            _contextMenu = new List<MenuItem>();
            Style = new XFItemStyle
            {
                BorderBottomColor = Color.FromArgb(189, 182, 189),
                DashStyleBottom = System.Drawing.Drawing2D.DashStyle.Dash,
                TextColor = Color.Black,
                TextFont = new Font(FontFamily.GenericSansSerif, 8, FontStyle.Regular),
                SelectedTextFont = new Font(FontFamily.GenericSansSerif, 8, FontStyle.Regular),
                SecondaryTextFont = new Font(FontFamily.GenericSansSerif, 7, FontStyle.Regular),
                SelectedSecondaryTextFont = new Font(FontFamily.GenericSansSerif, 7, FontStyle.Regular),
                SecondaryTextColor = Color.FromArgb(57, 52, 57),
                SelectedTextColor = Color.White,
                SelectedBackgroundColor = Color.FromArgb(43, 36, 43),
                SelectedSecondaryTextColor = Color.FromArgb(182, 178, 182),
                Padding = padding,
                PaddingTop = 18,
                PaddingBottom = 18
            };

            Control.Owner = this;
            TextBox.TextChanged += (o, e) =>
                                   {
                                       Text = ((TextBox)o).Text;
                                       if (TextChanged != null)
                                           TextChanged(this, new TextEventArgs(Text));
                                   };

            ItemType = XFItemType.ClickableNonChange;
        }

        private void RestoreMenuItems()
        {
            if (_contextMenu.Count == 0)
                return;

            var list = Parent as XFPanelList;
            if (list == null || list.Parent == null) return;

            var container = list.Parent;
            if (container.Parent == null || !(container.Parent is Form))
                return;

            var parent = container.Parent as Form;
            parent.Menu.MenuItems.Clear();

            foreach (MenuItem item in _contextMenu)
            {
                parent.Menu.MenuItems.Add(item);
            }
        }

        private void ReplaceMenuItems()
        {
            var list = Parent as XFPanelList;
            if (list == null || list.Parent == null)
                return;

            var container = list.Parent;
            if (container.Parent == null || !(container.Parent is Form))
                return;

            var parent = container.Parent as Form;

            _contextMenu.Clear();
            foreach (MenuItem item in parent.Menu.MenuItems)
            {
                _contextMenu.Add(item);
            }
            parent.Menu.MenuItems.Clear();

            var done = new MenuItem
                       {
                           Text = "Done"
                       };

            done.Click += (o, e) =>
            {
                list.OnBlur();
            };

            var cancel = new MenuItem
                         {
                             Text = "Cancel"
                         };

            cancel.Click += (o, e) =>
            {
                Text = _oldText;
                list.OnBlur();
            };

            parent.Menu.MenuItems.Add(done);
            parent.Menu.MenuItems.Add(cancel);
        }
    }
}
